<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <link rel="icon" href="public/favicon.ico" />
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Vue3 的 reactive 的演示</title>
  <script src="https://unpkg.com/vue@3.0.5/dist/vue.global.js"></script>
</head>
<body>
  <div>
    reactive 的演示...
  </div>
  <div id="app">
    <hr>
    person：{{person}}<br>
    myReatReadonly：{{myReatReadonly}}<br>
    myReatReadonly：{{myReatReadonly}}<br>

  </div>

  <script type="text/javascript">
    // ES6 的 Proxy 
    let onWatch = (obj, setBind, getLogger) => {
      let handler = {
        get(target, property, receiver) {
          getLogger(target, property)
          return Reflect.get(target, property, receiver)
        },
        set(target, property, value, receiver) {
          setBind(value, property)
          return Reflect.set(target, property, value)
        }
      }
      return new Proxy(obj, handler)
    }

  let obj = { a: 1 }
  let p = onWatch(
    obj,
    (v, property) => {
      console.log(`监听到属性${property}改变为${v}`)
    },
    (target, property) => {
      console.log(`'${property}' = ${target[property]}`)
    }
  )
  console.log(p)
  p.a = 2 // 监听到属性a改变

  </script>

  <script type="module">
    const App = {
      setup() {
        const person = Vue.reactive({
          name: 'jyk',
          age: 100,
          contact: {
            QQ: 122345,
            photo: 13012312314
          }
        })

        console.log('reactive:', person)
        console.log('reactive-Type:', typeof person)
        console.log('reactive-call:', Object.prototype.toString.call(person))

        // reactive 的 readonly
        const myReatReadonly = Vue.readonly(person)
        myReatReadonly.name = 'myReadonly' // 会出警告
        console.log('myReatReadonly:', myReatReadonly)

        // 普通对象的 readonly
        const myObjectReadonly = Vue.readonly({
          name:'object',
          age: 100
        })
        console.log('myObjectReadonly:', myObjectReadonly)

        // 简单类型的 readonly
        const myNumberReadonly = Vue.readonly(0) // 警告
        console.log('myNumberReadonly:', myNumberReadonly)

        // isProxy
        console.log('reactive:',Vue.isProxy(person))
        console.log('readonly:',Vue.isProxy(myReatReadonly))
        console.log('ObjectReadonly:',Vue.isProxy(myObjectReadonly))
        console.log('isProxy:',Vue.isProxy({name:'isProxy'}))
        console.log('-----------分隔符-----------')

        // isReactive
        console.log('reactive:',Vue.isReactive(person))
        console.log('readonly:',Vue.isReactive(myReatReadonly))
        console.log('ObjectReadonly:',Vue.isReactive(myObjectReadonly))
        console.log('isReactive:',Vue.isReactive({name:'isReactive'}))
        console.log('-----------分隔符-----------')

        // isReadonly
        console.log('reactive:',Vue.isReadonly(person))
        console.log('readonly:',Vue.isReadonly(myReatReadonly))
        console.log('ObjectReadonly:',Vue.isReadonly(myObjectReadonly))
        console.log('isReadonly:',Vue.isReadonly({name:'isReadonly'}))
        console.log('-----------分隔符-----------')

        // toRaw
        console.log('reactive:',Vue.toRaw(person))
        console.log('readonly:',Vue.toRaw(myReatReadonly))
        console.log('ObjectReadonly:',Vue.toRaw(myObjectReadonly))
        console.log('toRaw:',Vue.toRaw({name:'toRaw'}))

        return {
          person,
          myReatReadonly,
          myObjectReadonly
        }
      }
    }
    
    const vm = Vue.createApp(App).mount('#app')

  </script>
</body>
</html>
